﻿using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using SLua;
using Object = UnityEngine.Object;

public class LuaHelper
{
    public static string SystemCopyBuffer
    {
        get
        {
            return UniPasteBoard.GetClipBoardString();
        }
        set
        {
            UniPasteBoard.SetClipBoardString(value);
        }
    }

    public static void Destroy(Object original)
    {
        GameObject.Destroy(original);
    }

    public static void Destroy(Object original, float t)
    {
        GameObject.Destroy(original, t);
    }

    public static void DestroyImmediate(Object original)
    {
        GameObject.DestroyImmediate(original);
    }

    public static void DestroyImmediate(Object original, bool allowDestroyingAssets)
    {
        GameObject.DestroyImmediate(original, allowDestroyingAssets);
    }

    public static Object Instantiate(Object original)
    {
        return GameObject.Instantiate(original);
    }

    public static GameObject InstantiateLocal(GameObject original, Component parent)
    {
        return InstantiateLocal(original, parent, Vector3.zero);
    }

    private static GameObject InstantiateLocal(GameObject original, Component parent, Vector3 pos)
    {
        var tranformTa = original.transform;
        if (pos == Vector3.zero) pos = tranformTa.localPosition;
        Quaternion rota = tranformTa.localRotation;
        Vector3 scale = tranformTa.localScale;
        GameObject clone = (GameObject)GameObject.Instantiate(original);
        var transform = clone.transform;
        if (parent != null) clone.transform.SetParent(parent.transform);
        transform.localPosition = pos;
        transform.localScale = scale;
        transform.localRotation = rota;
        return clone;
    }

    public static void CloneTransform(Component target, Component source)
    {
        target.transform.localPosition = source.transform.localPosition;
        target.transform.localRotation = source.transform.localRotation;
        target.transform.localScale = source.transform.localScale;
    }

    public static void SetParent(Transform child, Component parent)
    {
        if (child == null || parent == null)
        {
            return;
        }

        var tranformTa = child;
        if (tranformTa.parent == parent.transform) return;

        if (tranformTa is RectTransform)
        {
            RectTransform rt = tranformTa as RectTransform;

            Vector3 anchoredPosition = rt.anchoredPosition3D;
            Vector2 sizeDelta = rt.sizeDelta;
            Quaternion roatation = tranformTa.localRotation;

            rt.SetParent(parent.transform);

            rt.anchoredPosition3D = anchoredPosition;
            rt.sizeDelta = sizeDelta;
            rt.localScale = Vector3.one;
            tranformTa.localRotation = roatation;
        }
        else
        {
            var pos = tranformTa.localPosition;
            var rota = tranformTa.localRotation;
            var scale = tranformTa.localScale;

            tranformTa.SetParent(parent.transform);

            tranformTa.localPosition = pos;
            tranformTa.localScale = scale;
            tranformTa.localRotation = rota;
        }
    }

    public static System.Type GetType(string classname)
    {
        if (string.IsNullOrEmpty(classname)) return null;

        System.Type t = null;
        Assembly[] assbs = System.AppDomain.CurrentDomain.GetAssemblies();
        Assembly assb = null;
        for (int i = 0; i < assbs.Length; i++)
        {
            assb = assbs[i];
            t = assb.GetType(classname);
            if (t != null) return t;
        }

        return null;
    }

    public static GameObject Find(string name)
    {
        return GameObject.Find(name);
    }

    public static GameObject FindWithTag(string tag)
    {
        return GameObject.FindWithTag(tag);
    }

    public static Component GetComponentInChildren(GameObject obj, string classname)
    {
        System.Type t = GetType(classname);
        return GetComponentInChildren(obj, t);
    }

    public static Component GetComponentInChildren(GameObject obj, System.Type t)
    {
        Component comp = null;

        try
        {
            comp = obj.GetComponentInChildren(t);
        }
        catch (System.Exception ex)
        {
            comp = null;
        }
        return comp;
    }


    public static Component FindComponentInChild(Component parent, string strChildName, System.Type t)
    {
        Component comp = null;
        try
        {
            comp = parent.transform.Find(strChildName).GetComponent(t);
        }
        catch (System.Exception ex)
        {
            comp = null;
        }
        return comp;
    }

    public static void SetChildActive(Component parent, string strChildName, bool bActive)
    {
        try
        {
            Transform trans = parent.transform.Find(strChildName);
            if (trans)
                trans.gameObject.SetActive(bActive);
        }
        catch (System.Exception ex)
        {
        }
    }

    public static void SetActive(Component parent, bool bActive)
    {
        try
        {
            parent.gameObject.SetActive(bActive);
        }
        catch (System.Exception ex)
        {
        }
    }

    //在Lua层保证参数的非空，
    public static Component FindComponentInChild(GameObject obj, string strChildName, System.Type t)
    {
        //Debuger.Log ("=========OBJ==========");
        return FindComponentInChild(obj.transform, strChildName, t);
    }

    public static Component GetComponentOfComp(Component fromComp, System.Type t)
    {
        Component comp = null;

        try
        {
            comp = fromComp.GetComponent(t);
        }
        catch (System.Exception ex)
        {
            comp = null;
        }
        return comp;
    }

    public static Component GetComponentEX(GameObject obj, System.Type t)
    {
        Component comp = GetComponent(obj, t);
        if (comp == null)
        {
            comp = obj.AddComponent(t);
        }
        return comp;
    }


    public static Component GetComponent(GameObject obj, string classname)
    {
        //Debuger.Log ("<color=red>=================string=====================</color>");
        System.Type t = GetType(classname);
        return GetComponent(obj, t);
    }

    public static Component GetComponent(GameObject obj, System.Type t)
    {
        Component comp = null;
        try
        {
            comp = obj.GetComponent(t);
        }
        catch (System.Exception ex)
        {
            comp = null;
        }
        return comp;
    }

    public static Component[] GetComponents(GameObject obj, string classname)
    {
        System.Type t = GetType(classname);
        return GetComponents(obj, t);
    }

    public static Component[] GetComponents(GameObject obj, System.Type t)
    {
        Component[] comp = null;
        if (obj != null && t != null) comp = obj.GetComponents(t);
        return comp;
    }

    public static Component[] GetComponentsInChildren(GameObject obj, string classname)
    {
        System.Type t = GetType(classname);
        return GetComponentsInChildren(obj, t);
    }

    public static Component[] GetComponentsInChildren(GameObject obj, System.Type t)
    {
        if (t != null && obj != null) return obj.transform.GetComponentsInChildren(t);
        return null;
    }


    public static GameObject GetChildFromName(GameObject parent, string name)
    {
        GameObject go = null;

        Transform p = parent.transform;
        Transform child = null;
        for (int i = 0; i < p.childCount; ++i)
        {
            child = p.GetChild(i);
            if (string.Equals(child.gameObject.name, name))
            {
                go = child.gameObject;
                break;
            }
        }

        return go;
    }

    public static Component GetChildComponentFromName(GameObject parent, string name, System.Type componentType)
    {
        GameObject go = GetChildFromName(parent, name);
        if (go == null)
        {
            return null;
        }

        return GetComponent(go, componentType);
    }

    public static void ForeachChild(GameObject parent, LuaFunction eachFn)
    {
        Transform pr = parent.transform;
        int count = pr.childCount;
        Transform child = null;
        for (int i = 0; i < count; ++i)
        {
            child = pr.GetChild(i);
            eachFn.call(i, child.gameObject);
        }
    }

    public static object Raycast(Ray ray)
    {
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit))
        {
            return hit;
        }
        return null;
    }

    public static System.Type GetObjectType(object obj)
    {
        return obj.GetType();
    }

    public static bool IsKindOf(object obj, System.Type type)
    {
        return obj.GetType() == type;
    }

    public static void RefreshShader(AssetBundle assetBundle)
    {
        Material[] materials = assetBundle.LoadAllAssets<Material>();
        for (int i = 0; i < materials.Length; ++i)
        {
            Material mat = materials[i];
            string shaderName = mat.shader.name;
            Shader newShader = Shader.Find(shaderName);
            if (newShader != null)
            {
                mat.shader = newShader;
            }
            else
            {
                Debuger.LogWarning("unable to refresh shader: {0} in material {1} ", shaderName, mat.name);
            }
        }
    }

    public static void RefreshShader(WWW www)
    {
        if (www.assetBundle != null)
        {
            RefreshShader(www.assetBundle);
        }
    }

    // 设置材质颜色
    public static void SetMaterialColor(GameObject go, Color color)
    {
        if (go == null)
        {
            return;
        }

        Renderer renderer = null;
        Material material = null;

        Renderer[] renderers = go.GetComponents<Renderer>();
        for (int i = 0; i < renderers.Length; ++i)
        {
            renderer = renderers[i];
            for (int j = 0; j < renderer.materials.Length; ++j)
            {
                material = renderer.materials[j];
                if (material.HasProperty("_Color"))
                {
                    material.SetColor("_Color", color);
                }
                else if (material.HasProperty("_TintColor"))
                {
                    material.SetColor("_TintColor", color);
                }
            }
        }
    }

    public static void SetMaterialAlpha(GameObject go, float alpha)
    {
        if (go == null)
        {
            return;
        }

        Renderer renderer = null;
        Material material = null;

        Renderer[] renderers = go.GetComponents<Renderer>();
        for (int i = 0; i < renderers.Length; ++i)
        {
            renderer = renderers[i];
            for (int j = 0; j < renderer.materials.Length; ++j)
            {
                material = renderer.materials[j];
                Color color = material.color;
                color.a = alpha;
                material.color = color;
            }
        }
    }

    public static float GetAngle(float p1x, float p1y, float p2x, float p2y)
    {
        var tmpx = p2x - p1x;
        var tmpy = p2y - p1y;
        var angle = Mathf.Atan2(tmpy, tmpx) * (180.0f / Mathf.PI);
        return angle;
    }

    public static Vector3 NormalizeV3(Vector3 v3)
    {
        return Vector3.Normalize(v3);
    }

    public static string GetUTF8String(System.Byte[] bytes)
    {
        return System.Text.Encoding.UTF8.GetString(bytes);
    }

    public static byte[] GetBytes(string utf8Str)
    {
        return System.Text.Encoding.UTF8.GetBytes(utf8Str);
    }

    public static void UnloadUnusedAssets()
    {
        Resources.UnloadUnusedAssets();
        System.GC.Collect();
    }

    // --------------------------------------------------------------------------------------------
    public static ByteArray GetByteArray(object data)
    {
        return new ByteArray(data as byte[]);
    }

    // 加密
    public static byte[] EncryptBytes(byte[] bytes)
    {
        byte[] ret = null;

        try
        {
            ConfigData data = Config.Instance.config;
            ret = CryptographHelper.Encrypt(bytes, data.Key, data.IV);
        }
        catch (System.Exception e)
        {
            Debuger.Log(e.Message);
        }

        return ret;
    }

    // 解密
    public static byte[] DecryptBytes(byte[] bytes)
    {
        byte[] ret = null;

        try
        {
            ConfigData data = Config.Instance.config;
            ret = CryptographHelper.Decrypt(bytes, data.Key, data.IV);
        }
        catch (System.Exception e)
        {
            Debuger.Log(e.Message);
        }
        return ret;
    }

    // --------------------------------------------------------------------------------------------
    // 文件相关
    public static bool IsFileExist(string path)
    {
        return File.Exists(path);
    }

    public static void DeleteFolder(string dir)
    {
        //		if (!string.IsNullOrEmpty (dir)) {
        //			dir = Config.PERSISTENT_DATA_PATH + "/" + dir;
        //		}
        //
        FileHelper.DeleteDirectory(dir);
    }

    public static void DeleteFile(string path)
    {
        FileHelper.DeleteFile(path);
    }

    public static void CreateDirectoryFromFile(string path)
    {
        FileHelper.CreateDirectoryFromFile(path);
    }

    public static List<string> GetAllFiles(string dir, string suffix)
    {
        return FileHelper.GetAllChildFiles(dir, suffix);
    }

    public static List<string> StringArrayToList(string[] data)
    {
        List<string> list = new List<string>();
        list.AddRange(data);

        return list;
    }

    // --------------------------------------------------------------------------------------------
    // 保存
    public static void SaveTextToFile(string text, string path)
    {
        FileHelper.SaveTextToFile(text, path);
    }

    public static void SaveBytesToFile(byte[] bytes, string path)
    {
        FileHelper.SaveBytesToFile(bytes, path);
    }

    // --------------------------------------------------------------------------------------------
    // 注册回调
    public static void RegisterFunc(string name, LuaFunction func)
    {
        LuaManager.Instance.RegisterFunc(name, func);
    }

    public static void UnregisterFunc(string name)
    {
        LuaManager.Instance.UnregisterFunc(name);
    }

    public static void GameReady()
    {
        EventBase.PostBase(EventID.START_FINISH);
    }

    public static bool IsRestart = false;
    public static void RestartGame()
    {
        EventBase.PostBase(EventID.START_GAME);
    }

    [DoNotToLua]
    public static object CallLuaFunction(string name)
    {
        object ret = null;
        if (LuaManager.Instance != null)
        {
            ret = LuaManager.Instance.CallFunc(name);
        }
        return ret;
    }

    [DoNotToLua]
    public static object CallLuaFunction(string name, object arg1)
    {
        object ret = null;
        if (LuaManager.Instance != null)
        {
            ret = LuaManager.Instance.CallFunc(name, arg1);
        }
        return ret;
    }
    [DoNotToLua]
    public static object CallLuaFunction(string name, object arg1, object arg2)
    {
        object ret = null;
        if (LuaManager.Instance != null)
        {
            ret = LuaManager.Instance.CallFunc(name, arg1, arg2);
        }
        return ret;
    }
    [DoNotToLua]
    public static object CallLuaFunction(string name, object arg1, object arg2, object arg3)
    {
        object ret = null;
        if (LuaManager.Instance != null)
        {
            ret = LuaManager.Instance.CallFunc(name, arg1, arg2, arg3);
        }
        return ret;
    }

    // --------------------------------------------------------------------------------------------
    // 本地调用
    public static string CallNative(string args)
    {
        return NativeManager.Instance.CallNative(args);
    }

    public static void SetNativeCallback(NativeManager.CallbackHandler func)
    {
        NativeManager.Instance.SetNativeCallback(func);
    }

    // 加载接口
    public static void LoadFile(string fullpath, LoadManager.LoadedCallback onLoaded, bool async, bool inData)
    {
        LoadManager.Instance.LoadFile(fullpath, onLoaded, async, inData);
    }

    public static void LoadAssetFile(string path, LoadManager.LoadedCallback onLoaded, System.Type type, bool async, bool inData)
    {
        LoadManager.Instance.LoadAssetFile(path, onLoaded, type, async, inData);
    }

    public static void LoadSprite(string atlas, string name, LoadManager.LoadedCallback onLoaded, bool async, bool useAtlas, bool needMaterial)
    {
        LoadManager.Instance.LoadSprite(atlas, name, onLoaded, async, useAtlas, needMaterial);
    }

    public static void LoadStream(string path, LoadManager.LoadedCallback onLoaded, bool async, bool remote, bool isFullPath)
    {
        LoadManager.Instance.LoadStream(path, onLoaded, async, remote, isFullPath);
    }

    public static void LoadAssetFromBundle(string Path, string name, System.Type type, LoadManager.LoadedCallback onLoaded, bool async, bool persistent)
    {
        LoadManager.Instance.LoadAssetFromBundle(Path, name, type, onLoaded, async, persistent);
    }

    public static void LoadAsset(string path, string name, string ext, System.Type type, LoadManager.LoadedCallback onLoaded, bool async, bool persistent, bool unload, bool isFullPath)
    {
        LoadManager.Instance.LoadAsset(path, name, ext, type, onLoaded, async, persistent, unload, isFullPath);
    }

    public static void UnloadAsset(string path, string name)
    {
        LoadManager.Instance.UnloadAsset(path, name);
    }

    public static void LoadScene(string name, LoadManager.LoadedCallback onLoaded, bool async)
    {
        LoadManager.Instance.LoadScene(name, onLoaded, async);
    }

    public static void LoadResource(string path, LoadManager.LoadedCallback onLoaded, bool async)
    {
        LoadManager.Instance.LoadResource(path, onLoaded, async);
    }

    public static void LoadFromCacheOrDownload(string url, string path, ResourceType tp, LoadManager.LoadedCallback onLoaded, bool async, bool onlyaCache)
    {
        LoadManager.Instance.LoadFromCacheOrDownload(url, path, tp, onLoaded, async, onlyaCache);
    }

    public static void LoadResourceFile(string fullpath, ResourceType tp, LoadManager.LoadedCallback onLoaded, bool async)
    {
        LoadManager.Instance.LoadResourceFile(fullpath, tp, onLoaded, async);
    }

    public static string GetBundlePath(string path, string defaultPath)
    {
        return LoadManager.Instance.GetBundlePath(path, defaultPath);
    }

    public static void UnloadBundle(string path, bool immediate)
    {
        LoadManager.Instance.UnloadBundle(path, immediate);
    }

    public static void UnloadScene(string name)
    {
        LoadManager.Instance.UnloadScene(name);
    }

    public static void ClearLoad()
    {
        LoadManager.Instance.Clear();
    }

    public static void BeginFrontLoad()
    {
        LoadManager.Instance.BeginFrontLoad();
    }

    public static void StartFrontLoad()
    {
        LoadManager.Instance.StartFrontLoad();
    }

    public static void WarmUpShaderVariants(string name, LoadManager.LoadedCallback onLoaded)
    {
        LoadManager.Instance.WarmUpShaderVariants(name, onLoaded);
    }

    // --------------------------------------------------------------------------------------------
    // 创建一个UI模糊遮罩
    public static Image CreateBlurMask(string shaderName, float r, float g, float b, float a)
    {
        GameObject go = new GameObject();

        Image image = go.AddComponent<Image>();
        image.color = new Color(r, g, b, a);
        image.material = new Material(Shader.Find(shaderName));

        return image;
    }

    // 相机是否有渲染指定的层
    public static bool IsCameraCullMask(Camera camera, int layer)
    {
        if (camera == null)
        {
            return false;
        }

        if (0 <= layer && layer <= 31)
        {
            return (camera.cullingMask & (1 << layer)) != 0;
        }
        else
        {
            return false;
        }
    }

    // 相机是否有渲染指定的层
    public static bool IsCameraCullMask(Camera camera, string layerName)
    {
        int layer = LayerMask.NameToLayer(layerName);
        return IsCameraCullMask(camera, layer);
    }

    static void SetLayer(Component[] items, int layer)
    {
        for (int i = 0; i < items.Length; ++i)
        {
            items[i].gameObject.layer = layer;
        }
    }

    // 将游戏对象设置到指定的层
    public static void SetLayer(GameObject go, int layer)
    {
        if (go == null)
        {
            return;
        }

        if (0 <= layer && layer <= 31)
        {
            SetLayer(go.GetComponentsInChildren<Renderer>(), layer);
            SetLayer(go.GetComponentsInChildren<CanvasRenderer>(), layer);
            SetLayer(go.GetComponentsInChildren<Canvas>(), layer);
        }
    }

    public static void SetLayer(GameObject go, string layerName)
    {
        int layer = LayerMask.NameToLayer(layerName);
        SetLayer(go, layer);
    }

    public static Material InitFlagMaterial(Material mat, Sprite sprite)
    {
        if (sprite.associatedAlphaSplitTexture != null)
        {
            mat.shader = LoadManager.Instance.GetShader("custom/flag/flagetc1.shader", "Custom/FlagETC1");

            mat.SetTexture("_MainTex", sprite.texture);
            mat.SetTexture("_AlphaTex", sprite.associatedAlphaSplitTexture);
        }
        else
        {
            mat.shader = LoadManager.Instance.GetShader("custom/flag/flagetc1.shader", "Custom/FlagETC1");

            mat.SetTexture("_MainTex", sprite.texture);
        }

        return mat;
    }

    public static Material InitAllianceFlagMaterial(Material mat, Sprite sprite)
    {
        if (mat == null || sprite == null)
        {
            return mat;
        }

        if (sprite.associatedAlphaSplitTexture != null)
        {
            mat.shader = LoadManager.Instance.GetShader("custom/flag/flagetc1.shader", "Custom/FlagETC1");

            mat.SetTexture("_MainTex", sprite.texture);
            mat.SetTexture("_AlphaTex", sprite.associatedAlphaSplitTexture);
        }
        else
        {
            mat.shader = LoadManager.Instance.GetShader("custom/flag/alliance_flag.shader", "Custom/Alliance_Flag");

            mat.SetTexture("_MainTex", sprite.texture);
        }

        return mat;
    }

    /// <summary>
    /// 获取对应Lua对象
    /// </summary>
    /// <param name="go"></param>
    /// <param name="luaClass"></param>
    /// <returns></returns>
    public static LuaTable GetLuaComponent(GameObject go, string luaClass = null)
    {
        LuaBehaviour luaComponent = go.GetComponent<LuaBehaviour>() ?? go.AddComponent<LuaBehaviour>();
        luaComponent.Initilize(luaClass);
        return luaComponent.LuaModule;
    }

    // --------------------------------------------------------------------------------------------
    // 阿语解析帮助 为联盟简称
    public static string FormatAbbr(string abbr)
    {
        StringBuilder sb = new StringBuilder();
        //        if (!SoarDText.GetRTL())
        //        {
        sb.Append('(').Append(abbr).Append(')');
        return sb.ToString();
        //        }
        //
        //        //断言为三个字符
        //        //非阿语
        //        if (!ArabicFixerTool.CheckRTL(abbr))
        //        {
        //            sb.Append('(').Append(abbr).Append(')').Append('￿');
        //            return sb.ToString();
        //        }
        //        //头尾阿语
        //        if (ArabicFixerTool.IsRTL(abbr[0]))
        //        {
        //            sb.Append('(').Append(abbr).Append("￿)");
        //        }
        //        //头数尾阿语
        //        else if (ArabicFixerTool.IsLTR(abbr[0]))
        //        {
        //            sb.Append(abbr[0]);
        //            if (ArabicFixerTool.IsLTR(abbr[1]))
        //            {
        //                sb.Append(abbr[1]).Append(')').Append(abbr[2]);
        //            }
        //            else
        //            {
        //                sb.Append(')').Append(abbr[1]).Append(abbr[2]);
        //            }
        //            sb.Append("￿)");
        //        }
        //        else
        //        {
        //            sb.Append('(').Append(abbr).Append(')');
        //        }
        //        sb.Append('￿');
        //        return sb.ToString();
    }

    public static void SetLanguage(string lang)
    {
        Config.Instance.Language = lang;
        PlayerPrefs.SetString(Config.KEY_LANGUAGE, lang);
    }

    public static string StringSub(string str, int start, int length)
    {

        if (str.Length <= length + start)
        {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++)
        {
            sb.Append(str[i + start]);
        }
        return sb.ToString();
    }


    public delegate void WWWDelegate(string msg);
    public delegate void WWWJsonDelegate(string msg, string error);
    public static WWWForm CreateWWWForm()
    {
        return new WWWForm();
    }


    static IEnumerator RequestWWWPos(string url, WWWForm form, WWWDelegate func)
    {
        WWW www = new WWW(url, form);
        yield return www;
        if (func != null)
        {
            func(www.text);
        }
    }

    static IEnumerator RequestWWWJson(string url, string form, WWWJsonDelegate func)
    {
        WWW www = new WWW(url, Encoding.UTF8.GetBytes(form));
        yield return www;
        if (func != null)
        {
            func(www.text, www.error);
        }
    }

    public static bool IsNull(Object obj)
    {
        return obj == null;
    }

    public static void ScreenToWorldPoint(Camera camera, Vector2 posScreen, out float x, out float y, out float z)
    {
        x = 0;
        y = 0;
        z = 0;
        if (camera == null)
        {
            return;
        }

        Vector3 posCamera = camera.transform.position;
        Vector3 posWorld = camera.ScreenToWorldPoint(new Vector3(posScreen.x, posScreen.y, 99));

        // 过摄影机以及离摄像机10单位的平面对应屏幕点的直线，与格子平面的交点
        // 联立直线与平面方程，交点即格子坐标系坐标
        // y = 0(格子平面)
        // (x-x1)/(x2-x1)=(y-y1)/(y2-y1)=(z-z1)/(z2-z1)(过两点M1(x1,y1,z1),M2(x2,y2,z2)的空间直线方程)
        x = ((0 - posWorld.y / (posCamera.y - posWorld.y)) * (posCamera.x - posWorld.x)) + posWorld.x;
        z = ((0 - posWorld.y / (posCamera.y - posWorld.y)) * (posCamera.z - posWorld.z)) + posWorld.z;
    }
    static Plane plane = new Plane(Vector3.up, Vector3.zero);
    public static void ScreenToWorldPointForOrthoCam(Camera camera, float posScreen_x, float posScreen_y, float depth, out float x, out float y, out float z)
    {
        x = 0;
        y = 0;
        z = 0;
        if (camera == null)
        {
            return;
        }

        Ray ray = camera.ScreenPointToRay(new Vector3(posScreen_x, posScreen_y));
        float enter = 0.0f;
        if (plane.Raycast(ray, out enter))
        {
            Vector3 hitPoint = ray.GetPoint(enter);
            x = hitPoint.x;
            z = hitPoint.z;
        }
    }
    public static Vector3 GetCameraRayPosition(Camera camera, Vector3 position)
    {
        if (camera == null)
        {
            return Vector3.zero;
        }

        Vector3 rotatEuler = camera.transform.rotation.eulerAngles;
        float distance = camera.transform.position.z / Mathf.Tan(rotatEuler.x / 180 * Mathf.PI) * Mathf.Sin(rotatEuler.z / 180 * Mathf.PI);
        return new Vector3(position.x - distance, 0, position.z - distance);
    }

    public static void SetPersistentABs(string[] arrAB)
    {
        LoadManager.Instance.SetPersistentABs(arrAB);
    }

    public static void UISetParent(GameObject go, Transform p)
    {
        if (go == null)
        {
            Debuger.LogError("param go is null");
            return;
        }

        if (p == null)
        {
            Debuger.LogError("param parent is null");
            return;
        }

        if (go.transform.parent == p) return;
        go.transform.SetParent(p);
    }

    public static void SetLRGridGroup(GridLayoutGroup gp)
    {
        gp.startCorner = GridLayoutGroup.Corner.UpperLeft;
    }

    public static void SetRectTransOffset(RectTransform transfrom, RectTransform transto)
    {
        transto.offsetMin = transfrom.offsetMin;
        transto.offsetMax = transfrom.offsetMax;
    }

    //判断某个点是否在摄像机范围内
    public static bool IsPointInsideCamera(Camera main, float x, float y, float z)
    {
        Vector3 pos = new Vector3(x, y, z);
        Vector3 sPos = main.WorldToScreenPoint(pos);
        if (GameDefine.ScreenSize.x < sPos.x || sPos.x < 0 || GameDefine.ScreenSize.y < sPos.y || sPos.y < 0)
        {
            return false;
        }
        return true;
    }

    public static bool IsPosInsideScreen(Camera main, float x, float y, float z)
    {
        Vector3 pos = new Vector3(x, y, z);
        Vector3 sPos = main.WorldToScreenPoint(pos);
        return sPos.x < 0 || sPos.y < 0 || sPos.x > Screen.width || sPos.y > Screen.height;
    }

    public static bool IsPosInsideCameraViewPort(Camera main, float x, float y, float z)
    {
        Vector3 pos = new Vector3(x, y, z);
        Vector3 posViewport = main.WorldToViewportPoint(pos);
        return -0.4f <= posViewport.x && posViewport.x <= 1.4f && -0.15f <= posViewport.y && posViewport.y <= 1.05f;
    }


    public static void SetImageAlpha(Image img, float alpha)
    {
        try
        {
            Color clor = img.color;
            clor.a = alpha;
            img.color = clor;
        }
        catch (System.Exception ex) { }
    }

    public static float GetEffectDuration(GameObject go)
    {
        float maxDuration = -1f;
        ParticleSystem[] particles = go.GetComponentsInChildren<ParticleSystem>();
        ParticleSystem particle = null;
        for (int i = 0; i < particles.Length; ++i)
        {
            particle = particles[i];
            if (particle.enableEmission)
            {
                //if (particle.loop) {
                //	return -1f;
                //}

                float dunration = 0f;
                if (particle.emissionRate <= 0)
                {
                    dunration = particle.startDelay + particle.startLifetime;
                }
                else
                {
                    dunration = particle.startDelay + Mathf.Max(particle.duration, particle.startLifetime);
                }

                if (dunration > maxDuration)
                {
                    maxDuration = dunration;
                }
            }
        }

        return maxDuration;
    }

    public static Vector2 ScreenPointToCanvasLocalPosition(Vector2 position, Canvas canvas)
    {
        Vector2 localPos;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.GetComponent<RectTransform>(), position, canvas.worldCamera, out localPos);
        return localPos;
    }

    public static Vector2 ScreenPointToCanvasLocalPosition(Vector3 position, Canvas canvas)
    {
        Vector2 localPos;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.GetComponent<RectTransform>(), position, canvas.worldCamera, out localPos);
        return localPos;
    }

    public static LTDescr MoveByPath(GameObject ob, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, float time)
    {
        Vector3[] path = new Vector3[] { v1, v2, v3, v4 };
        return LeanTween.move(ob, path, time);
    }

    /// <summary>
    /// 获取汉字首字母
    /// </summary>
    /// <param name="CnStr"></param>
    /// <returns></returns>
    public static string GetSpellCode(string text)
    {
        StringBuilder strTemp = new StringBuilder();
        int iLen = text.Length;
        int i;
        for (i = 0; i <= iLen - 1; i++)
            strTemp.Append(GetCharSpellCode(text.Substring(i, 1)));
        return strTemp.ToString();
    }

    /// <summary>
    /// 获取首字母ASCII码
    /// </summary>
    /// <param name="CnStr"></param>
    /// <returns></returns>
    public static int GetFristWord(string text)
    {
        if (!string.IsNullOrEmpty(text))
        {
            byte[] bytes = Encoding.Default.GetBytes(GetCharSpellCode(text.Substring(0, 1)));
            return bytes[0];
        }
        return 0;
    }

    /// <summary>
    /// 得到一个汉字的拼音第一个字母，如果是一个英文字母则直接返回大写字母
    /// </summary>
    /// <param name="CnChar">单个汉字</param>
    /// <returns>单个大写字母</returns>
    private static string GetCharSpellCode(string CnChar)
    {
        long iCnChar;
        byte[] ZW = Encoding.Default.GetBytes(CnChar);

        //如果是字母，则直接返回

        if (ZW.Length == 1)
        {
            return CnChar.ToUpper();
        }
        else
        {
            int i1 = ZW[0];
            int i2 = ZW[1];
            iCnChar = i1 * 256 + i2;
        }

        if ((iCnChar >= 45217) && (iCnChar <= 45252))
            return "A";
        if ((iCnChar >= 45253) && (iCnChar <= 45760))
            return "B";
        if ((iCnChar >= 45761) && (iCnChar <= 46317))
            return "C";
        if ((iCnChar >= 46318) && (iCnChar <= 46825))
            return "D";
        if ((iCnChar >= 46826) && (iCnChar <= 47009))
            return "E";
        if ((iCnChar >= 47010) && (iCnChar <= 47296))
            return "F";
        if ((iCnChar >= 47297) && (iCnChar <= 47613))
            return "G";
        if ((iCnChar >= 47614) && (iCnChar <= 48118))
            return "H";
        if ((iCnChar >= 48119) && (iCnChar <= 49061))
            return "J";
        if ((iCnChar >= 49062) && (iCnChar <= 49323))
            return "K";
        if ((iCnChar >= 49324) && (iCnChar <= 49895))
            return "L";
        if ((iCnChar >= 49896) && (iCnChar <= 50370))
            return "M";
        if ((iCnChar >= 50371) && (iCnChar <= 50613))
            return "N";
        if ((iCnChar >= 50614) && (iCnChar <= 50621))
            return "O";
        if ((iCnChar >= 50622) && (iCnChar <= 50905))
            return "P";
        if ((iCnChar >= 50906) && (iCnChar <= 51386))
            return "Q";
        if ((iCnChar >= 51387) && (iCnChar <= 51445))
            return "R";
        if ((iCnChar >= 51446) && (iCnChar <= 52217))
            return "S";
        if ((iCnChar >= 52218) && (iCnChar <= 52697))
            return "T";
        if ((iCnChar >= 52698) && (iCnChar <= 52979))
            return "W";
        if ((iCnChar >= 52980) && (iCnChar <= 53640))
            return "X";
        if ((iCnChar >= 53689) && (iCnChar <= 54480))
            return "Y";
        if ((iCnChar >= 54481) && (iCnChar <= 55289))
            return "Z";
        return ("?");
    }

    public static void ParseEmojiString(LuaTable table)
    {
        int length = table.length();
        for (int i = 1; i <= length; i++)
        {
            LuaTable tb = (LuaTable)table[i];
            string icon = tb["icon"].ToString();
            tb["text"] = GetConvertedString(icon);
            //if (icon.IndexOf('_') == -1)
            //    tb["code"] = Convert.ToInt32(icon, 16);
        }
    }

    private static string GetConvertedString(string inputString)
    {
        string[] converted = inputString.Split('-');
        for (int j = 0; j < converted.Length; j++)
        {
            string str = converted[j];
            if (str.IndexOf('_') == -1)
                converted[j] = char.ConvertFromUtf32(Convert.ToInt32(str, 16));
        }
        return string.Join(string.Empty, converted);
    }
}
